package cn.com.pajx.pajx_visitor_v3.utils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

import cn.com.pajx.pajx_visitor_v3.base.BaseActivity;

/**
 * Created by ruancw on 2024/2/28.
 * Description: 静默安装的实现类
 */
public class SilentInstall {

    /**
     * 执行具体的静默安装逻辑，需要手机ROOT。
     *
     * @param apkPath 要安装的apk文件的路径
     * @param context context
     * @return 安装成功返回true，安装失败返回false。
     */
    public static boolean install(String apkPath, BaseActivity context) {
        boolean result = false;
        DataOutputStream dataOutputStream = null;
        BufferedReader errorStream = null;
        Process process;
        try {
            // 申请su权限
            process = Runtime.getRuntime().exec("su");
            dataOutputStream = new DataOutputStream(process.getOutputStream());
            // 执行pm install命令
            String command = "pm install -r " + apkPath + "\n";
            dataOutputStream.write(command.getBytes(StandardCharsets.UTF_8));
            dataOutputStream.flush();
            dataOutputStream.writeBytes("exit\n");
            dataOutputStream.flush();
            process.waitFor();
            errorStream = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            StringBuilder msg = new StringBuilder();
            String line;
            // 读取命令的执行结果
            while ((line = errorStream.readLine()) != null) {
                msg.append(line);
            }
            LogUtils.e("install msg is " + msg);
            // 如果执行结果中包含Failure字样就认为是安装失败，否则就认为安装成功
            if (!msg.toString().contains("Failure")) {
                result = true;
            }
        } catch (Exception e) {
            LogUtils.e(Objects.requireNonNull(e.getMessage()));
        } finally {
            try {
                if (dataOutputStream != null) {
                    dataOutputStream.close();
                }
                if (errorStream != null) {
                    errorStream.close();
                }
            } catch (IOException e) {
                LogUtils.e("SilentInstall=" + e.getMessage());
            }
        }
        return result;
    }

    public static boolean silentInstall(Context context, String filePath) {
        File file = new File(filePath);
        PackageManager packageManager = context.getPackageManager();
        Class<?> pmClz = packageManager.getClass();
        try {
            if (Build.VERSION.SDK_INT >= 21) {
                @SuppressLint("PrivateApi")
                Class<?> aClass = Class.forName("android.app.PackageInstallObserver");
                Constructor<?> constructor = aClass.getDeclaredConstructor();
                constructor.setAccessible(true);
                Object installObserver = constructor.newInstance();
                Method method = pmClz.getDeclaredMethod("installPackage", Uri.class, aClass, int.class, String.class);
                method.setAccessible(true);
                method.invoke(packageManager, Uri.fromFile(file), installObserver, 2, null);
            } else {
                Method method = pmClz.getDeclaredMethod("installPackage",
                        Uri.class, Class.forName("android.content.pm.IPackageInstallObserver"), int.class, String.class);
                method.setAccessible(true);
                method.invoke(packageManager, Uri.fromFile(file), null, 2, null);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

}